#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <string>
#include "RingQueue.hpp"

using namespace std;

static const size_t C_NUM = 5;
static const size_t P_NUM = 5;

struct ThreadData
{
    RingQueue<int>* rq;
    string name;
};

void* Producer(void* args)
{
    ThreadData* td = static_cast<ThreadData*>(args);
    while(true) {
        // 获取数据
        int data = rand() % 10;
        const char* name = td->name.c_str();
        RingQueue<int>* rq = td->rq;
        // 生产数据
        rq->Push(data);
        printf("%s, put data: %d\n", name, data);
        // sleep(1);
    }
    delete td;
    return nullptr;
}

void* Consumer(void* args)
{
    ThreadData* td = static_cast<ThreadData*>(args);
    while(true) {
        // 消费数据
        int data = 0;
        const char* name = td->name.c_str();
        RingQueue<int>* rq = td->rq;
        rq->Pop(&data);
        printf("%s, put data: %d\n", name, data);
        // 处理数据
        sleep(1);
    }
    delete td;
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));
    RingQueue<int>* rq = new RingQueue<int>();
    pthread_t c[C_NUM], p[P_NUM];
    for(size_t i = 0; i < P_NUM;++i) {
        ThreadData* pTd = new ThreadData();
        pTd->rq = rq;
        pTd->name = "Producer Thread-" + to_string(i+1);
        pthread_create(c+i, nullptr, Producer, pTd);
    }
    for(size_t i = 0; i < C_NUM;++i) {
        ThreadData* cTd = new ThreadData();
        cTd->rq = rq;
        cTd->name = "Consumer Thread-" + to_string(i+1);
        pthread_create(p+i, nullptr, Consumer, cTd);
    }
    for(size_t i = 0; i < P_NUM;++i)
        pthread_join(c[i], nullptr);
    for(size_t i = 0; i < C_NUM;++i)
        pthread_join(p[i], nullptr);
    delete rq;
    return 0;
}